package com.hx.voice.recognition.auth.server.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hx.voice.recognition.auth.server.bean.ClientInfo;
import com.hx.voice.recognition.auth.server.entity.AuthClient;
import com.hx.voice.recognition.auth.server.feign.IUserService;
import com.hx.voice.recognition.auth.server.mapper.AuthClientMapper;
import com.hx.voice.recognition.auth.server.service.IAuthClientService;
import com.hx.voice.recognition.auth.server.util.client.ClientTokenUtil;
import com.hx.voice.recognition.auth.server.util.user.JwtAuthenticationRequest;
import com.hx.voice.recognition.auth.server.util.user.JwtTokenUtil;
import com.hx.zjb.security.api.vo.user.UserInfo;
import com.hx.zjb.security.auth.common.util.jwt.JWTInfo;
import com.hx.zjb.security.common.exception.auth.ClientInvalidException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author jack
 * @since 2019-06-13
 */
@Service
public class AuthClientServiceImpl extends ServiceImpl<AuthClientMapper, AuthClient> implements IAuthClientService {

    @Autowired
    private ClientTokenUtil clientTokenUtil;

    @Autowired
    private AuthClientMapper clientMapper;

    @Autowired
    private DiscoveryClient discoveryClient;

    private ApplicationContext context;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Autowired
    private IUserService userService;

    @Override
    public String apply(String client, String secret) throws Exception {
        AuthClient authClient =  getClient(client,secret);
        return clientTokenUtil.generateToken(new ClientInfo(authClient.getCode(),authClient.getName(),authClient.getId().toString()));

    }

    @Override
    public List<String> getAllowedClient(String serviceId, String secret) {
        AuthClient client = this.getClient(serviceId, secret);
        //获取被允许调用的应用
        List<String> clientIds = clientMapper.getAllowedClient(client.getId());
        if(CollUtil.isEmpty(clientIds))
        {
            clientIds = new ArrayList<>();
        }
        return clientIds;
    }

    @Override
    public void validate(String clientId, String secret) {
        getClient(clientId, secret);
    }

    @Override
    public String login( JwtAuthenticationRequest authenticationRequest) throws Exception {
        UserInfo user = userService.validate(authenticationRequest);
        String token = jwtTokenUtil.generateToken(new JWTInfo(user.getUsername(),String.valueOf(user.getId()),user.getName()));
        return token;
    }

    @Override
    public String refreshToken(String token) throws Exception {
        return jwtTokenUtil.generateToken(jwtTokenUtil.getInfoFromToken(token));
    }

    @Override
    public void verify(String token) throws Exception {
        jwtTokenUtil.getInfoFromToken(token);
    }

    @Override
    public List<String> getAllowedClient(String clientId) {
        AuthClient client = this.getClient(clientId);
        //获取被允许调用的应用
        List<String> clientIds = clientMapper.getAllowedClient(client.getId());
        if(CollUtil.isEmpty(clientIds))
        {
            clientIds = new ArrayList<>();
        }
        return clientIds;
    }

    private AuthClient getClient(String clientId) {
        return this.getOne(new QueryWrapper<AuthClient>().eq("code", clientId));
    }

    /**
     * @description 根据clientId和secret查找应用
     * @method  getClient
     * @param  [client, secret]
     * @return com.hx.zjb.security.auth.server.entity.AuthClient
     * @date: 2019/6/14 10:48
     * @author:zhoujinbing
     */
    private AuthClient getClient(String client, String secret) {
        AuthClient authClient = this.getOne(new QueryWrapper<AuthClient>().eq("code", client));
        if(ObjectUtil.isEmpty(authClient) || !authClient.getSecret().equals(secret))
        {
            throw new ClientInvalidException("Client not found or Client Secret is error!");
        }
        return authClient;
    }


}
